package com.glp.work.flow.handler.flowable;

import com.glp.common.reponse.BaseResult;
import com.glp.work.flow.constant.APICode;
import com.glp.work.flow.constant.OrderOperation;
import com.glp.work.flow.constant.ProcessVariablesEnum;
import com.glp.work.flow.exception.APIException;
import com.glp.work.flow.mapper.WfPlatformDefModleMapper;
import com.glp.work.flow.pojo.RoleCodes;
import com.glp.work.flow.pojo.WfPlatformDefModle;
import com.glp.work.flow.pojo.WfTaskAssignRole;
import com.glp.work.flow.pojo.WfTaskAssignUsers;
import com.glp.work.flow.service.OrderInfoService;
import com.glp.work.flow.service.client.PermissionClient;
import com.glp.work.flow.workflow.plugin.flowable.constant.FlowConstant;
import com.glp.work.flow.workflow.plugin.flowable.service.FlowProcessDefinitionService;
import lombok.extern.slf4j.Slf4j;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author pengjia
 * @version 2020年8月7日 下午2:45:41
 */
@Service("mutiInstanceHandler")
@Slf4j
class MutiInstanceHandler implements Serializable {

    private static final long serialVersionUID = -2812574530257308696L;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private PermissionClient permissionService;
    @Autowired
    private FlowProcessDefinitionService flowProcessDefinitionService;
    @Autowired
    private WfPlatformDefModleMapper wfPlatformDefModleMapper;


    public List<String> getTaskUsers(DelegateExecution execution) {
        @SuppressWarnings("unchecked")
        List<String> userNos = (List<String>) execution.getVariables().get(ProcessVariablesEnum.DYNAMIC_USER_ASSIGN.name());
        if (CollectionUtils.isEmpty(userNos)) {
            String proDefId = execution.getProcessDefinitionId();
            String taskDefKey = execution.getCurrentActivityId();
            log.info("【会签：查询可被分配任务的用户】查询被分配任务的用户！根据流程定义ID：{}，任务定义KEY：{}，", proDefId, taskDefKey);
            List<WfTaskAssignUsers> userList = orderInfoService.queryTaskAssignUsers(proDefId, taskDefKey);
            log.info("【会签：查询可被分配任务的用户】查询被分配任务的角色！根据流程定义ID：{}，任务定义KEY：{}，", proDefId, taskDefKey);
            List<WfTaskAssignRole> roleList = orderInfoService.queryTaskAssignRoles(proDefId, taskDefKey);
            if (CollectionUtils.isEmpty(userList) && CollectionUtils.isEmpty(roleList)) {
                throw new APIException(APICode.DATA_ERROR, "没有分配用户或者角色");
            }
            RoleCodes roleCodes = new RoleCodes();
            List<String> codes = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(roleList)) {
                for (WfTaskAssignRole wfTaskAssignRole : roleList) {
                    log.info("会签：角色对应的code:{}", wfTaskAssignRole.getRoleCode());
                    codes.add(wfTaskAssignRole.getRoleCode());
                }
                roleCodes.setRoleCodeList(codes);
                BaseResult<?> listBaseResult = permissionService.personInfosByRoleCodeList(roleCodes);
                if (listBaseResult.getCode() != 200) {
                    throw new APIException(APICode.ERROR, "会签：调用根据角色得到对应的用户列表失败！！");
                }
                log.info("会签：根据角色得到对应的用户信息:{}", listBaseResult);
                @SuppressWarnings("unchecked")
                List<Map<String, String>> data = (List<Map<String, String>>) listBaseResult.getData();
                for (Map<String, String> user : data) {
                    String userNo = user.get("userNo");
                    WfTaskAssignUsers users = new WfTaskAssignUsers();
                    users.setUserNo(userNo);
                    userList.add(users);
                }
            }
            userNos = userList.stream().map(WfTaskAssignUsers::getUserNo).collect(Collectors.toList());
            log.info("【会签：查询可被分配任务的用户】流程定义ID：{}，任务定义KEY：{}，被分配任务的用户：{}", proDefId, taskDefKey, userNos);
            return userNos;
        }
        return userNos;
    }

    public boolean getComplete(DelegateExecution execution) {
        String auditResult = (String) execution.getVariable(FlowConstant.AUDIT_PASS);
        Integer nrOfCompletedInstances = (Integer) execution.getVariable("nrOfCompletedInstances");
        Integer nrOfInstances = (Integer) execution.getVariable("nrOfInstances");
        log.info("会签：判断会签任务是否完成！auditResult={}，nrOfCompletedInstances={}，nrOfInstances={}", auditResult, nrOfCompletedInstances, nrOfInstances);
        if (execution.getCurrentFlowElement().getName().contains(FlowConstant.COUNTERSIGN_NAME_VOTE)) {
            String s = execution.getVariables().get(FlowConstant.MODEL_KEY).toString();
            log.info("[会签投票制]：modelKey：{}", s);
            WfPlatformDefModle wfPlatformDefModle = new WfPlatformDefModle();
            wfPlatformDefModle.setModelKey(s);
            int i = wfPlatformDefModleMapper.selectCount(wfPlatformDefModle);
            log.info("[会签投票制]：配置app数量：{}", i);
            int agreePerson = 0;
            if (OrderOperation.PASS.name().equalsIgnoreCase(auditResult.trim())) {
                Object object = execution.getVariableLocal(FlowConstant.MULTIINSTANCE_AGREE_COUNTER);
                if (object == null) {
                    agreePerson = 1;
                    execution.setVariableLocal(FlowConstant.MULTIINSTANCE_AGREE_COUNTER, 1);
                } else {
                    agreePerson = Integer.parseInt(object.toString()) + 1;
                    execution.setVariableLocal(FlowConstant.MULTIINSTANCE_AGREE_COUNTER, agreePerson);
                }
            }
            log.info("[会签投票制]：同意数量：{}", agreePerson);
            if (agreePerson >= i) {
                return true;
            } else {
                return false;
            }
        } else {
            if (OrderOperation.REJECT.name().equalsIgnoreCase(auditResult.trim())
                    || OrderOperation.REJECT_TO_UP.name().equalsIgnoreCase(auditResult.trim())) {
                return true;
            } else {
                if (nrOfCompletedInstances.compareTo(nrOfInstances) == 0) {
                    log.info("会签：任务完成！nrOfCompletedInstances={}，nrOfInstances={}", nrOfCompletedInstances, nrOfInstances);
                    return true;
                } else {
                    return false;
                }
            }
        }
    }

}
